#! /usr/bin/python3


import hashlib
import json
import sys
import threading
import time
import os
import uuid
import soundfile as sf

import queue
from ws4py.client.threadedclient import WebSocketClient


def encrypt(s):
    hash = hashlib.sha256()
    hash.update(s.encode('utf-8'))
    return hash.hexdigest()


class YouDaoClient(WebSocketClient):
    cfg = {
        "appKey": None,
        "salt": str(uuid.uuid1()),
        "curtime": str(int(time.time())),
        "sign": None,
        "signType": "v4",
        "from": "en",
        "to": "zh-CHS",
        "version": "v1",
        "channel": "1",
        "format": "wav",
        "rate": "16000",
        "transPattern": "stream"
    }

    def __init__(self, cfg):
        self.zoom = None
        self.segId = 0
        self.cfg['from'] = cfg['from']
        self.cfg['to'] = cfg['to']
        self.cfg['appKey'] = cfg['key']
        self.cfg['sign'] = encrypt(
            cfg['key'] + self.cfg["salt"] + self.cfg["curtime"] + cfg['secret'])

        url = "wss://openapi.youdao.com/stream_speech_trans?"
        arg = ""
        for (key, val) in self.cfg.items():
            if arg != "":
                arg += "&"
            arg += key + "=" + val
        super(YouDaoClient, self).__init__(url+arg)
        print("connect:\n    ", url+arg)

        self.record_queue = queue.Queue(10)
        self.connect()

    def push(self, data):
        self.record_queue.put(data)

    def opened(self):
        def send_data():
            running = True
            while running:
                try:
                    raw = self.record_queue.get(block=True, timeout=2)
                except:
                    break

                wav_path = "tmp.wav"
                sf.write(wav_path, raw, 16000)
                with open(wav_path, 'rb+') as wav_file:
                    while True:
                        wav_data = wav_file.read(6400)
                        try:
                            self.send(wav_data, binary=True)
                            if len(wav_data) < 6400:
                                break
                        except:
                            print('error')
                            running = False
                            break

            #self.send('{\"end\": \"true\"}')
        self.back_thread = threading.Thread(target=send_data)
        self.back_thread.start()

    def received_message(self, text):
        try:
            res = json.loads(str(text))["result"]
            self.send_text.push(
                res["segId"], res["context"], res["tranContent"])
        except:
            pass


if __name__ == '__main__':
    pass
